package sg.edu.nus.iss.jass.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.swing.DefaultCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import sg.edu.nus.iss.jass.model.CompanyDTO;
import sg.edu.nus.iss.jass.model.JobAdvertDTO;
import sg.edu.nus.iss.jass.model.SkillDTO;

/**
 * @version 1.0
 * @author SE19 Team 1
 * 
 */
public class ViewJobAdvertPanel extends JPanel {
	private static final long serialVersionUID = 1L;
	
	public static final String BTN_EDIT_JOBADVERT = "btnEditJobAdvert";
	public static final String BTN_WITHDRAW_JOBADVERT = "btnWithdrawJobAdvert";
	public static final String BTN_DELETE_JOBADVERT = "btnDeleteJobAdvert";
	public static final String BTN_BACK_TO_SEARCH = "btnBackToSearch";
	
	private int numRows = 0;
	private Properties properties;
	private JButton btnEditJobAdvert, btnWithdrawJobAdvert, btnDeleteJobAdvert, btnBackToSearch;
	private JTextArea txtJobDesc;
	private String[] columnNames = new String[4];
	private JobAdvertDTO jobAdvertDTO;
	private DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
	
	private DefaultTableModel defaultTableModel = new DefaultTableModel() {
		private static final long serialVersionUID = 1L;
		
		public boolean isCellEditable(int row, int column) {
			return false;
		}
		
		public Class<?> getColumnClass(int columnIndex) {
			if (columnIndex == 0)
				return Boolean.class;
			else
				return super.getColumnClass(columnIndex);
		}
	};
	private JTable skillTable = new JTable(defaultTableModel);
	
	// Class Constructor.
	public ViewJobAdvertPanel(JobAdvertDTO jobAdvertDTO) {
		this.setOpaque(false);
		this.setLayout(new BorderLayout());
		this.jobAdvertDTO = jobAdvertDTO;
		
		loadConfiguration();
		initColumnNameArray();
		add(constructJobAdvertPanel(), BorderLayout.CENTER);
	}
	
	public void addComponentActionListener(ActionListener listener) {
		btnEditJobAdvert.addActionListener(listener);
		btnWithdrawJobAdvert.addActionListener(listener);
		btnDeleteJobAdvert.addActionListener(listener);
		btnBackToSearch.addActionListener(listener);
	}
	
	public String getJobAdvertId() {
		return jobAdvertDTO.getId().trim();
	}
	
	private void loadConfiguration() {
		try {
			properties = new Properties();
			FileInputStream in = new FileInputStream("properties/application.properties");
			properties.load(in);
			in.close();
		}
		catch(Exception ex) {
			ex.printStackTrace();
		}
	}
	
	private void initColumnNameArray() {
		columnNames[0] = "";
		columnNames[1] = properties.getProperty("table.column.skillDesc");
		columnNames[2] = properties.getProperty("table.column.type");
		columnNames[3] = properties.getProperty("table.column.proficiency");
	}
	
	private JPanel constructJobAdvertPanel() {
		// 1. To determine the title of the Job Advert.
		String jobAdvertTitle = properties.getProperty("title.jobadvert.viewJobAdvert");
		
		// 2. Construct Customer Details Panel
		GridBagLayout jobAdvertGridLayout = new GridBagLayout();
		JPanel jobAdvertDetailPanel = new JPanel(jobAdvertGridLayout);
		jobAdvertDetailPanel.setOpaque(false);
		
		JLabel label;
		label = createLabel(properties.getProperty("label.jobadvert.RefCode"));
		addRow(jobAdvertDetailPanel, label, createDataLabel(jobAdvertDTO.getReferenceCode()));
		
		label = createLabel(properties.getProperty("label.jobadvert.title"));
		addRow(jobAdvertDetailPanel, label, createDataLabel(jobAdvertDTO.getJobTitle()));
		
		label = createLabel(properties.getProperty("label.jobadvert.desc"));
		txtJobDesc = createTextArea();
		txtJobDesc.setText(jobAdvertDTO.getJobDescription());
		txtJobDesc.setEditable(false);
		addRow(jobAdvertDetailPanel, label, new JScrollPane(txtJobDesc));
		
		label = createLabel(properties.getProperty("label.jobadvert.yearOfExp"));
		addRow(jobAdvertDetailPanel, label, createDataLabel(jobAdvertDTO.getYearOfExperience().toString()));
		
		label = createLabel(properties.getProperty("label.jobadvert.salaryRange"));
		addRow(jobAdvertDetailPanel, label, createDataLabel(retrieveSalaryDesc()));
		
		label = createLabel(properties.getProperty("label.jobadvert.startDate"));
		addRow(jobAdvertDetailPanel, label, createDataLabel(df.format(jobAdvertDTO.getStartDate())));

		label = createLabel(properties.getProperty("label.jobadvert.location"));
		addRow(jobAdvertDetailPanel, label, createDataLabel(jobAdvertDTO.getLocation()));

		label = createLabel(properties.getProperty("label.jobadvert.skill"));
		skillTable = constructSkillTable();
		addRow(jobAdvertDetailPanel, label, new JScrollPane(skillTable));
		
		label = createLabel(properties.getProperty("label.jobadvert.company"));
		String displayName = "";
		CompanyDTO companyDTO = jobAdvertDTO.getCompany();
		if(!companyDTO.getIsAnonymous().booleanValue())
			displayName = companyDTO.getName();
		else
			displayName = companyDTO.getAlternativeDesc();
		addRow(jobAdvertDetailPanel, label, createDataLabel(displayName));

		label = createLabel(properties.getProperty("label.jobadvert.advertOwner"));
		addRow(jobAdvertDetailPanel, label, createDataLabel(jobAdvertDTO.getAdvertiser()));
		
		label = createLabel(properties.getProperty("label.jobadvert.status"));
		addRow(jobAdvertDetailPanel, label, createDataLabel(JobAdvertDTO.JOBADVERT_STATUS[jobAdvertDTO.getStatus() - 1]));
		
		JPanel buttonPanel = new JPanel();
		buttonPanel.setOpaque(false);
		buttonPanel.setLayout(new GridLayout(0, 2, 5, 5));
		
		btnEditJobAdvert = new JButton(properties.getProperty("button.label.editJobAdvert"));
		btnEditJobAdvert.setName(BTN_EDIT_JOBADVERT);
		btnEditJobAdvert.setFont(new Font("Calibri", Font.BOLD, 16));
		btnWithdrawJobAdvert = new JButton(properties.getProperty("button.label.withdrawJobAdvert"));
		btnWithdrawJobAdvert.setName(BTN_WITHDRAW_JOBADVERT);
		btnWithdrawJobAdvert.setFont(new Font("Calibri", Font.BOLD, 16));
		btnDeleteJobAdvert = new JButton(properties.getProperty("button.label.deleteJobAdvert"));
		btnDeleteJobAdvert.setName(BTN_DELETE_JOBADVERT);
		btnDeleteJobAdvert.setFont(new Font("Calibri", Font.BOLD, 16));
		btnBackToSearch = new JButton(properties.getProperty("button.label.backToSearch"));
		btnBackToSearch.setName(BTN_BACK_TO_SEARCH);
		btnBackToSearch.setFont(new Font("Calibri", Font.BOLD, 16));
		buttonPanel.add(btnEditJobAdvert);
		buttonPanel.add(btnWithdrawJobAdvert);
		buttonPanel.add(btnDeleteJobAdvert);
		buttonPanel.add(btnBackToSearch);
		
		addRow(jobAdvertDetailPanel, null, buttonPanel);
		
		// 3. Construct Header Panel
		JPanel headerPanel = new JPanel();
		headerPanel.setOpaque(false);
		headerPanel.setLayout(new GridLayout(0, 1, 10, 10));
		
		JLabel msgLabel = new JLabel(jobAdvertTitle);
		msgLabel.setFont(new Font("Calibri", Font.PLAIN, 30));
		msgLabel.setHorizontalAlignment(SwingConstants.CENTER);
		headerPanel.add(msgLabel);
		
		ImageIcon imgDivider = new ImageIcon("./images/divider.jpg");
		JLabel lblDivider = new JLabel(imgDivider);
		headerPanel.add(lblDivider);
		
		JPanel jobAdvertPanel = new JPanel();
		jobAdvertPanel.setOpaque(false);
		jobAdvertPanel.setLayout(new BorderLayout());
		jobAdvertPanel.add(headerPanel, BorderLayout.NORTH);
		jobAdvertPanel.add(jobAdvertDetailPanel, BorderLayout.CENTER);
		
		return jobAdvertPanel;
	}

	private void addRow(JPanel panel, Component label, Component component) {
		GridBagConstraints constraints = new GridBagConstraints();
		constraints.insets = new Insets(5, 5, 5, 5);
		constraints.fill = GridBagConstraints.HORIZONTAL;
		
		if(label != null) {
			constraints.gridx = 0;
			constraints.gridy = numRows;
			panel.add(label, constraints);
		}
		
		if(component != null) {
			constraints.gridx = 1;
			constraints.gridy = numRows;
			panel.add(component, constraints);
		}
		numRows++;
	}
	
	private JLabel createLabel(String label) {
		JLabel jlabel = new JLabel(label);
		jlabel.setFont(new Font("Calibri", Font.BOLD, 16));
		jlabel.setHorizontalAlignment(JLabel.RIGHT);
		jlabel.setVerticalAlignment(JLabel.TOP);
		return jlabel;
	}
	
	private JLabel createDataLabel(String label) {
		JLabel jlabel = new JLabel(label);
		jlabel.setFont(new Font("Calibri", Font.PLAIN, 16));
		jlabel.setHorizontalAlignment(JLabel.LEFT);
		jlabel.setVerticalAlignment(JLabel.TOP);
		return jlabel;
	}

	private JTextArea createTextArea() {
		JTextArea textarea = new JTextArea(5, 40);
		textarea.setFont(new Font("Calibri", Font.PLAIN, 16));
		return textarea;
	}
	
	private String retrieveSalaryDesc() {
		StringTokenizer st = new StringTokenizer(jobAdvertDTO.getSalaryRange(), ",");
		String salRanges = "From $" + st.nextToken() + " To $" + st.nextToken();
		return salRanges;
	}
	
	private JTable constructSkillTable() {
		List<SkillDTO> skills = jobAdvertDTO.getSkills();
		Object[][] data = new Object[skills.size()][4];
		for(int n = 0; n < skills.size(); n++) {
			SkillDTO skillDTO = skills.get(n);
			
			data[n][0] = new Boolean(true);
			data[n][1] = skillDTO.getDescription();
			data[n][2] = skillDTO.getType();
			data[n][3] = skillDTO.getProficiencyLevel();
		}
		
		defaultTableModel.setDataVector(data, columnNames);
		skillTable.setModel(defaultTableModel);
		
		//Set Table Columns widths Begin
		JCheckBox checkbox = new JCheckBox();
		checkbox.setEnabled(false);
		TableColumn col = skillTable.getColumnModel().getColumn(0);
		col.setCellEditor(new DefaultCellEditor(checkbox));
	    col.setPreferredWidth(10);
	    
	    col = skillTable.getColumnModel().getColumn(1);
	    col.setPreferredWidth(200);
	    col = skillTable.getColumnModel().getColumn(2);
	    col.setPreferredWidth(80);
	    
	  	//Set Table Columns widths Begin
	    skillTable.setPreferredScrollableViewportSize(new Dimension(470,80));
	    skillTable.setFont(new Font("Calibri", Font.PLAIN, 12));
	    skillTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	    
	    return skillTable;
	}
	
	public void displayDeleteSuccessMsg() {
		JOptionPane.showMessageDialog(this, "Job Advertisement Deleted Successfully.", "Delete Job Advert", JOptionPane.INFORMATION_MESSAGE);
	}
	
	public void displayWithdrawSuccessMsg() {
		JOptionPane.showMessageDialog(this, "Job Advertisement Withdrawal Successfully.", "Withdraw Job Advert", JOptionPane.INFORMATION_MESSAGE);
	}
}
